﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Web;
using System.Web.UI.WebControls;

namespace APMAWebConsole.PlanningPart
{
    public partial class Tasks : System.Web.UI.Page
    {
        private const string TasksDataSourceKey = "TasksDataSourceKey";
        private const string UsersListKey = "UsersListKey";
        private const string ProjectsListKey = "ProjectsListKey";
        private const string UserStoriesListKey = "UserStoriesListKey";
        private const string IsEditModeKey = "IsEditModeKey";
        private const string IsUpdateKey = "IsUpdateKey";
        private const string UploadedFileListKey = "UploadedFileListKey";
        private const string IsAfterFileUploadPostbackKey = "IsAfterFileUploadPostbackKey";

        public DataTable DataSource
        {
            get
            {
                return ViewState[TasksDataSourceKey] != null
                           ? (DataTable) ViewState[TasksDataSourceKey]
                           : (DataTable)(ViewState[TasksDataSourceKey] = SiteMaster.Proxy.GetTasksList());
            }

            set { ViewState[TasksDataSourceKey] = value; }
        }

        public DataTable UsersList
        {
            get
            {
                return ViewState[UsersListKey] != null
                           ? (DataTable)ViewState[UsersListKey]
                           : (DataTable)(ViewState[UsersListKey] = SiteMaster.Proxy.GetUsersList());
            }

            set { ViewState[UsersListKey] = value; }
        }

        public DataTable ProjectsList
        {
            get
            {
                return ViewState[ProjectsListKey] != null
                           ? (DataTable)ViewState[ProjectsListKey]
                           : (DataTable)(ViewState[ProjectsListKey] = SiteMaster.Proxy.GetProjectsList());
            }

            set { ViewState[ProjectsListKey] = value; }
        }

        public DataTable UserStoriesList
        {
            get
            {
                return ViewState[UserStoriesListKey] != null
                           ? (DataTable)ViewState[UserStoriesListKey]
                           : (DataTable)(ViewState[UserStoriesListKey] = SiteMaster.Proxy.GetUserStoriesList());
            }

            set { ViewState[UserStoriesListKey] = value; }
        }

        private DataTable UploadedFileList
        {
            get
            {
                if(ViewState[UploadedFileListKey] != null)
                    return (DataTable) ViewState[UploadedFileListKey];

                if (IsUpdate)
                {
                    var selectedRow = SelectedRow;

                    if (selectedRow == -1)
                    {
                        ViewState[UploadedFileListKey] = CreateEmptyUploadedFilesTable();
                        return (DataTable)ViewState[UploadedFileListKey];
                    }

                    int intParseValue;
                    var isParsed = int.TryParse(DataSource.Rows[selectedRow]["Id"].ToString(), out intParseValue);

                    if (!isParsed)
                    {
                        ViewState[UploadedFileListKey] = CreateEmptyUploadedFilesTable();
                        return (DataTable)ViewState[UploadedFileListKey];
                    }

                    var filesTable = SiteMaster.Proxy.GetFilesListByTask(intParseValue);
                    filesTable.TableName = "UploadedFileList";
                    ViewState[UploadedFileListKey] = filesTable;
                }
                else
                {
                    ViewState[UploadedFileListKey] = CreateEmptyUploadedFilesTable();
                }

                return (DataTable)ViewState[UploadedFileListKey];
            }

            set { ViewState[UploadedFileListKey] = value; }
        }

        private DataTable CreateEmptyUploadedFilesTable()
        {
            var idColumn = new DataColumn("Id", typeof(int));
            var fileNameColumn = new DataColumn("Name", typeof(string));
            var fileByteColumn = new DataColumn("FileByte", typeof(byte[]));

            var dataTable = new DataTable();
            dataTable.Columns.AddRange(new DataColumn[]
                        {
                            idColumn,
                            fileNameColumn,
                            fileByteColumn
                        }
                );
            dataTable.TableName = "UploadedFileList";

            return dataTable;
        }

        public bool IsEditMode
        {
            set { ViewState[IsEditModeKey] = value; }
            get { return ViewState[IsEditModeKey] != null && (bool) ViewState[IsEditModeKey]; }
        }

        public bool IsUpdate
        {
            set { ViewState[IsUpdateKey] = value; }
            get { return ViewState[IsUpdateKey] != null && (bool)ViewState[IsUpdateKey]; }
        }

        private bool IsAfterFileUploadPostback
        {
            set { ViewState[IsAfterFileUploadPostbackKey] = value; }
            get { return ViewState[IsAfterFileUploadPostbackKey] != null && (bool)ViewState[IsAfterFileUploadPostbackKey]; }
        }

        private int SelectedRow
        {
            get
            {
                int selectedRow;
                var isSuccessfully = int.TryParse(txtSelectedTask.Text, out selectedRow);

                if (isSuccessfully && selectedRow - 1 >= 0 && selectedRow - 1 < DataSource.Rows.Count 
                        && DataSource.Rows[selectedRow - 1] != null)
                    return selectedRow - 1;

                return -1;
            }
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            if (!Page.User.Identity.IsAuthenticated)
                Response.Redirect("~/Account/Login.aspx");
        }

        private void Rebind()
        {
            if (IsEditMode)
            {
                txtTaskId.Enabled = false;

                ddlTaskOwnerId.Items.Clear();
                ddlTaskOwnerId.DataValueField = "Id";
                ddlTaskOwnerId.DataTextField = "Name";
                ddlTaskOwnerId.DataSource = UsersList;
                ddlTaskOwnerId.DataBind();
                ddlTaskOwnerId.Items.Insert(0, new ListItem(String.Empty, String.Empty));

                ddlTaskProjectId.Items.Clear();
                ddlTaskProjectId.DataValueField = "Id";
                ddlTaskProjectId.DataTextField = "Name";
                ddlTaskProjectId.DataSource = ProjectsList;
                ddlTaskProjectId.DataBind();
                ddlTaskProjectId.Items.Insert(0, new ListItem(String.Empty, String.Empty));

                ddlTaskUserStoryId.Items.Clear();
                ddlTaskUserStoryId.DataValueField = "Id";
                ddlTaskUserStoryId.DataTextField = "Name";
                ddlTaskUserStoryId.DataSource = UserStoriesList;
                ddlTaskUserStoryId.DataBind();
                ddlTaskUserStoryId.Items.Insert(0, new ListItem(String.Empty, String.Empty));

                ddlTaskStateId.Items.Clear();
                ddlTaskStateId.DataValueField = "Id";
                ddlTaskStateId.DataTextField = "Name";
                ddlTaskStateId.Items.Insert(0, new ListItem(String.Empty, String.Empty));
                ddlTaskStateId.Items.Insert(1, new ListItem("Defined", "1"));
                ddlTaskStateId.Items.Insert(2, new ListItem("Completed", "2"));
                ddlTaskStateId.Items.Insert(3, new ListItem("In progress", "3"));

                if (!IsUpdate)
                {
                    txtTaskId.Text = txtTaskName.Text = txtTaskDescription.Text = txtTaskEstimate.Text =
                                                                              txtTaskActuals.Text =
                                                                              txtTaskToDo.Text =
                                                                              txtTaskNotes.Text = "";
                    ddlTaskOwnerId.SelectedIndex = 0;
                    ddlTaskProjectId.SelectedIndex = 0;
                    ddlTaskUserStoryId.SelectedIndex = 0;
                    ddlTaskStateId.SelectedIndex = 0;
                }
                else
                {
                    var selectedRow = SelectedRow;

                    if (selectedRow == -1)
                        return;

                    txtTaskId.Text = DataSource.Rows[selectedRow]["Id"].ToString();
                    txtTaskName.Text = DataSource.Rows[selectedRow]["Name"].ToString();
                    txtTaskDescription.Text = DataSource.Rows[selectedRow]["Description"].ToString();
                    txtTaskEstimate.Text = DataSource.Rows[selectedRow]["Estimate"].ToString();
                    txtTaskActuals.Text = DataSource.Rows[selectedRow]["Actuals"].ToString();
                    txtTaskToDo.Text = DataSource.Rows[selectedRow]["To_do"].ToString();
                    txtTaskNotes.Text = DataSource.Rows[selectedRow]["Notes"].ToString();

                    ddlTaskOwnerId.SelectedValue = DataSource.Rows[selectedRow]["Owner_id"].ToString() != "" 
                                                    ? DataSource.Rows[selectedRow]["Owner_id"].ToString()
                                                    : null;

                    ddlTaskStateId.SelectedValue = DataSource.Rows[selectedRow]["State_id"].ToString() != ""
                                                    ? DataSource.Rows[selectedRow]["State_id"].ToString()
                                                    : null;

                    ddlTaskProjectId.SelectedValue = DataSource.Rows[selectedRow]["Project_id"].ToString() != ""
                                                    ? DataSource.Rows[selectedRow]["Project_id"].ToString()
                                                    : null;

                    ddlTaskUserStoryId.SelectedValue = DataSource.Rows[selectedRow]["User_story_id"].ToString() != ""
                                                    ? DataSource.Rows[selectedRow]["User_story_id"].ToString()
                                                    : null;
                }
            }
            else
            {
                grdTasks.DataSource = DataSource;
                grdTasks.DataBind();
            }
        }

        private void RebindUploadedFilesGrid()
        {
            if (!IsEditMode)
                return;

            grdUploadedFiles.DataSource = UploadedFileList;
            grdUploadedFiles.DataBind();
        }

        protected override void OnLoadComplete(EventArgs e)
        {
            base.OnLoadComplete(e);

            if(!IsAfterFileUploadPostback)
                Rebind();

            IsAfterFileUploadPostback = false;
            RebindUploadedFilesGrid();
        }

        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);

            divEditMode.Visible = IsEditMode;
            divTasksGrid.Visible = !IsEditMode;

            btnAddTask.Visible = !IsEditMode;
            btnEditTask.Visible = btnRemoveTask.Visible = false;
            btnBackToList.Visible = IsEditMode;

            if (IsEditMode)
            {
                btnCreateUpdate.Text = IsUpdate ? "Update" : "Create";
            }
        }

        protected void btnServerFileUpload_Click(object sender, EventArgs e)
        {
            if (inputUploadFile.PostedFile != null)
            {

                var myFile = inputUploadFile.PostedFile;

                // Get size of uploaded file
                var nFileLen = myFile.ContentLength;

                var myData = new byte[nFileLen];

                myFile.InputStream.Read(myData, 0, nFileLen);

                var newRow = UploadedFileList.NewRow();
                newRow["Name"] = myFile.FileName;
                newRow["FileByte"] = myData;

                UploadedFileList.Rows.Add(newRow);

                grdUploadedFiles.DataBind();
                updUploadFiles.Update();

                IsAfterFileUploadPostback = true;
            }
        }

        protected void btnDownloadFile_OnClick(object sender, EventArgs e)
        {
            int selectedRow;
            var isSuccessfully = int.TryParse(txtDownloadFileID.Text, out selectedRow);

            if (!isSuccessfully || selectedRow - 1 < 0 || selectedRow - 1 >= UploadedFileList.Rows.Count ||
                UploadedFileList.Rows[selectedRow - 1] == null)
            {
                return;
            }

            var fileName = UploadedFileList.Rows[selectedRow - 1]["Name"].ToString();
            var buffer = (byte[])UploadedFileList.Rows[selectedRow - 1]["FileByte"];


            long fileSize = (long)buffer.Length;
            Response.Clear();
            Response.ContentType = "application/oc-stream";

            Response.AddHeader("Content-Disposition", "attachement;filename=" + HttpUtility.UrlEncode(fileName));
            //   
            Response.AddHeader("Content-Length", fileSize.ToString());
            //Response.OutputStream.Write(buffer, 0, (int)buffer.Length);

            Response.BinaryWrite(buffer);
            Response.Flush();
            Response.Close();
        }

        protected void btnRemoveLast_OnClick(object sender, EventArgs e)
        {
            if (UploadedFileList.Rows.Count == 0)
                return;

            UploadedFileList.Rows.RemoveAt(UploadedFileList.Rows.Count - 1);

            grdUploadedFiles.DataBind();
            updUploadFiles.Update();
        }
        
        protected void OnButtonCommand(object sender, CommandEventArgs e)
        {
            switch (e.CommandName)
            {
                case "Add":
                    {
                        IsEditMode = true;
                        IsUpdate = false;
                        UploadedFileList = null;

                        break;
                    }
                case "Remove":
                    {
                        if (e.CommandArgument.ToString() != "")
                            txtSelectedTask.Text = e.CommandArgument.ToString();

                        RemoveTask();

                        break;
                    }
                case "Edit":
                    {
                        IsEditMode = true;
                        IsUpdate = true;
                        UploadedFileList = null;

                        break;
                    }

                case "Select":
                    {
                        txtSelectedTask.Text = e.CommandArgument.ToString();
                        IsEditMode = true;
                        IsUpdate = true;
                        UploadedFileList = null;

                        break;
                    }

                case "SaveUpdate":
                    {
                        if (IsEditMode)
                        {
                            if (IsUpdate)
                            {
                                UpdateTask();
                            }
                            else
                            {
                                SaveTask();
                            }
                        }

                        break;
                    }

                case "BackToList":
                    {
                        IsEditMode = false;
                        UploadedFileList = null;

                        break;
                    }
            }

            Rebind();
        }

        private Dictionary<string, object> PrepareParameters(Dictionary<string, object> parameters)
        {
            parameters.Add("Name", txtTaskName.Text);

            int intParseValue;

            var isParsed = int.TryParse(ddlTaskOwnerId.SelectedValue, out intParseValue);
            parameters.Add("Owner_id", isParsed ? (int?)intParseValue : null);

            isParsed = int.TryParse(ddlTaskProjectId.SelectedValue, out intParseValue);
            parameters.Add("Project_id", isParsed ? (int?)intParseValue : null);

            parameters.Add("Description", txtTaskDescription.Text);

            isParsed = int.TryParse(ddlTaskStateId.SelectedValue, out intParseValue);
            parameters.Add("State_id", isParsed ? (int?)intParseValue : null);

            isParsed = int.TryParse(txtTaskEstimate.Text, out intParseValue);
            parameters.Add("Estimate", isParsed ? (int?)intParseValue : null);

            isParsed = int.TryParse(txtTaskActuals.Text, out intParseValue);
            parameters.Add("Actuals", isParsed ? (int?)intParseValue : null);

            isParsed = int.TryParse(txtTaskToDo.Text, out intParseValue);
            parameters.Add("To_do", isParsed ? (int?)intParseValue : null);

            isParsed = int.TryParse(ddlTaskUserStoryId.SelectedValue, out intParseValue);
            parameters.Add("User_story_id", isParsed ? (int?)intParseValue : null);

            parameters.Add("Notes", txtTaskNotes.Text);

            return parameters;
        }

        private bool ValidateFields()
        {
            return Page.IsValid;
        }

        private void SaveTask()
        {
            if (!ValidateFields())
                return;

            var parameters = PrepareParameters(new Dictionary<string, object>());

            var insertedId = SiteMaster.Proxy.AddNewTask(parameters, Page.User.Identity.Name);

            if (UploadedFileList.Rows.Count != 0)
                SiteMaster.Proxy.AddFilesToTask(UploadedFileList, insertedId);

            IsEditMode = false;
            DataSource = null;
            UploadedFileList = null;
        }

        private void UpdateTask()
        {
            if (!ValidateFields())
                return;

            var parameters = new Dictionary<string, object>();

            int intParseValue;
            var isParsed = int.TryParse(txtTaskId.Text, out intParseValue);

            if (!isParsed)
                return;

            parameters.Add("Id", intParseValue);

            parameters = PrepareParameters(parameters);

            SiteMaster.Proxy.UpdateTask(parameters, Page.User.Identity.Name);

            SiteMaster.Proxy.AddFilesToTask(UploadedFileList, intParseValue);

            IsEditMode = false;
            DataSource = null;
            UploadedFileList = null;
        }

        private void RemoveTask()
        {
            var selectedRow = SelectedRow;

            if (selectedRow == -1)
                return;

            int intParseValue;
            var isParsed = int.TryParse(DataSource.Rows[selectedRow]["Id"].ToString(), out intParseValue);

            if (!isParsed)
                return;

            SiteMaster.Proxy.RemoveTask(intParseValue, Page.User.Identity.Name);

            IsEditMode = false;
            DataSource = null;
        }

    }
}